﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;
using Lucene.Net.Index;
using System.IO;
using System.Web.Caching;
using search.tradetuber.com;

namespace Lucene.Net.Extension
{
    public class GroupByFieldCache
    {
        //public static Dictionary<string, ModelFieldCache> CacheDic = new Dictionary<string, ModelFieldCache>();
        //public static Dictionary<string, List<string>> StandardMemberCompanyIDCache = new Dictionary<string, List<string>>();
        private readonly static object GroupByFieldCacheLockObj = new object();
        private readonly static object GroupByFieldCacheLockObjByTimeB = new object();
        private readonly static object GroupByFieldCacheLockObjByTimeP = new object();
        private readonly static object GroupByFieldCacheLockObjByCreditIndex = new object();
        //public readonly static object LockObjBySMCC = new object();

        /// <summary>
        /// 卖家索引库CompanyID缓存
        /// </summary>
        /// <param name="_IndexReader"></param>
        /// <param name="GroupBy"></param>
        /// <returns></returns>
        public static Dictionary<int, string> GetCompanyIDFieldCache(IndexReader _IndexReader, TermName _TermName, TermCacheName _TermCacheName)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();
            string strCacheName = "TermFieldCache" + _TermCacheName.ToString();
            Cache modelCache = System.Web.HttpRuntime.Cache;

            dict = (Dictionary<int, string>)modelCache[strCacheName];
            if (dict == null)
            {
                lock (GroupByFieldCacheLockObj)
                {
                    dict = (Dictionary<int, string>)modelCache[strCacheName];
                    if (dict == null)
                    {
                        dict = AddTermCache(_TermName, _TermCacheName, _IndexReader);
                        modelCache.Insert(strCacheName, dict, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);
                    }
                }
            }
            return dict;

            //DateTime dtStart = DateTime.Now;
            //ModelFieldCache modelFieldCache = new ModelFieldCache();

            //if (CacheDic.ContainsKey(_TermCacheName.ToString()))
            //{
            //    int oldMaxDoc = CacheDic[_TermCacheName.ToString()].MaxDoc;
            //    int newMaxDoc = _IndexReader.MaxDoc();
            //    modelFieldCache = CacheDic[_TermCacheName.ToString()];
            //    if (oldMaxDoc < newMaxDoc)
            //    {
            //        lock (LockObj)
            //        {
            //            UpdateTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //else
            //{
            //    lock (LockObj)
            //    {
            //        if (!CacheDic.ContainsKey(_TermCacheName.ToString()))
            //        {
            //            AddTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //DateTime dtEnd = DateTime.Now;
            //double intTime = dtEnd.Subtract(dtStart).TotalSeconds;
            //return CacheDic[_TermCacheName.ToString()].FieldValueCache;
        }

        /// <summary>
        /// 买家索引库ItemCreateTime缓存
        /// </summary>
        /// <param name="_IndexReader"></param>
        /// <param name="GroupBy"></param>
        /// <returns></returns>
        public static Dictionary<int, string> GetTimeFieldCacheByB(IndexReader _IndexReader, TermName _TermName, TermCacheName _TermCacheName)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();
            string strCacheName = "TermFieldCache" + _TermCacheName.ToString();
            Cache modelCache = System.Web.HttpRuntime.Cache;

            dict = (Dictionary<int, string>)modelCache[strCacheName];
            if (dict == null)
            {
                lock (GroupByFieldCacheLockObjByTimeB)
                {
                    dict = (Dictionary<int, string>)modelCache[strCacheName];
                    if (dict == null)
                    {
                        dict = AddTermCache(_TermName, _TermCacheName, _IndexReader);
                        modelCache.Insert(strCacheName, dict, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);
                    }
                }
            }
            return dict;

            //ModelFieldCache modelFieldCache = new ModelFieldCache();
            //if (CacheDic.ContainsKey(_TermCacheName.ToString()))
            //{
            //    int oldMaxDoc = CacheDic[_TermCacheName.ToString()].MaxDoc;
            //    int newMaxDoc = _IndexReader.MaxDoc();
            //    modelFieldCache = CacheDic[_TermCacheName.ToString()];
            //    if (oldMaxDoc < newMaxDoc)
            //    {
            //        lock (LockObjByTimeB)
            //        {
            //            UpdateTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //else
            //{
            //    lock (LockObjByTimeB)
            //    {
            //        if (!CacheDic.ContainsKey(_TermCacheName.ToString()))
            //        {
            //            AddTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}

            //return CacheDic[_TermCacheName.ToString()].FieldValueCache;
        }

        /// <summary>
        /// 卖家索引库ItemCreateTime缓存
        /// </summary>
        /// <param name="_IndexReader"></param>
        /// <param name="GroupBy"></param>
        /// <returns></returns>
        public static Dictionary<int, string> GetTimeFieldCacheByP(IndexReader _IndexReader, TermName _TermName, TermCacheName _TermCacheName)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();
            string strCacheName = "TermFieldCache" + _TermCacheName.ToString();
            Cache modelCache = System.Web.HttpRuntime.Cache;

            dict = (Dictionary<int, string>)modelCache[strCacheName];
            if (dict == null)
            {
                lock (GroupByFieldCacheLockObjByTimeP)
                {
                    dict = (Dictionary<int, string>)modelCache[strCacheName];
                    if (dict == null)
                    {
                        dict = AddTermCache(_TermName, _TermCacheName, _IndexReader);
                        modelCache.Insert(strCacheName, dict, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);
                    }
                }
            }
            return dict;

            //DateTime dtStart = DateTime.Now;
            //ModelFieldCache modelFieldCache = new ModelFieldCache();
            //if (CacheDic.ContainsKey(_TermCacheName.ToString()))
            //{
            //    int oldMaxDoc = CacheDic[_TermCacheName.ToString()].MaxDoc;
            //    int newMaxDoc = _IndexReader.MaxDoc();
            //    modelFieldCache = CacheDic[_TermCacheName.ToString()];
            //    if (oldMaxDoc < newMaxDoc)
            //    {
            //        lock (LockObjByTimeP)
            //        {
            //            UpdateTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //else
            //{
            //    lock (LockObjByTimeP)
            //    {
            //        if (!CacheDic.ContainsKey(_TermCacheName.ToString()))
            //        {
            //            AddTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //DateTime dtEnd = DateTime.Now;
            //double intTime = dtEnd.Subtract(dtStart).TotalSeconds;
            //return CacheDic[_TermCacheName.ToString()].FieldValueCache;
        }

        /// <summary>
        /// CreditIndex字段缓存
        /// </summary>
        /// <param name="_IndexReader"></param>
        /// <param name="GroupBy"></param>
        /// <returns></returns>
        public static Dictionary<int, string> GetCreditIndexFieldCache(IndexReader _IndexReader, TermName _TermName, TermCacheName _TermCacheName)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();
            string strCacheName = "TermFieldCache" + _TermCacheName.ToString();
            Cache modelCache = System.Web.HttpRuntime.Cache;

            dict = (Dictionary<int, string>)modelCache[strCacheName];
            if (dict == null)
            {
                lock (GroupByFieldCacheLockObjByCreditIndex)
                {
                    dict = (Dictionary<int, string>)modelCache[strCacheName];
                    if (dict == null)
                    {
                        dict = AddTermCache(_TermName, _TermCacheName, _IndexReader);
                        modelCache.Insert(strCacheName, dict, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);
                    }
                }
            }
            return dict;
            //DateTime dtStart = DateTime.Now;
            //ModelFieldCache modelFieldCache = new ModelFieldCache();
            //if (CacheDic.ContainsKey(_TermCacheName.ToString()))
            //{
            //    int oldMaxDoc = CacheDic[_TermCacheName.ToString()].MaxDoc;
            //    int newMaxDoc = _IndexReader.MaxDoc();
            //    modelFieldCache = CacheDic[_TermCacheName.ToString()];
            //    if (oldMaxDoc < newMaxDoc)
            //    {
            //        lock (LockObjByCreditIndex)
            //        {
            //            UpdateTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //else
            //{
            //    lock (LockObjByCreditIndex)
            //    {
            //        if (!CacheDic.ContainsKey(_TermCacheName.ToString()))
            //        {
            //            AddTermCache(_TermName, _TermCacheName, _IndexReader, modelFieldCache);
            //        }
            //    }
            //}
            //DateTime dtEnd = DateTime.Now;
            //double intTime = dtEnd.Subtract(dtStart).TotalSeconds;
            //return CacheDic[_TermCacheName.ToString()].FieldValueCache;
        }

        private static Dictionary<int, string> AddTermCache(TermName _TermName, TermCacheName _TermCacheName, IndexReader _IndexReader)
        {
            Dictionary<int, string> dict = new Dictionary<int, string>();
            //int intMaxDoc = 0;
            bool FileExist = false;

            //判断是否存在缓存文件，存在则直接从缓存文件中读取，否则从索引库中读取
            string strTermCacheFilePath = GlobalVariable.strServerPath + "Search\\";
            DirectoryInfo dir = new DirectoryInfo(strTermCacheFilePath);
            FileInfo[] fileInfoList = dir.GetFiles(@"*.txt", SearchOption.TopDirectoryOnly);
            foreach (FileInfo fileInfo in fileInfoList)
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(fileInfo.Name, string.Format(@"{0}", _TermCacheName.ToString())))
                {
                    FileExist = true;

                    using (StreamReader _StreamReaderKey = new StreamReader(strTermCacheFilePath + fileInfo.Name))
                    {
                        string strLine = "";
                        while (!string.IsNullOrEmpty((strLine = _StreamReaderKey.ReadLine())))
                        {
                            string[] strArr = strLine.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                            dict.Add(Convert.ToInt32(strArr[0]), strArr[1]);
                        }
                    }
                   
                    break;
                }
            }
            if (!FileExist)
            {
                //intMaxDoc = _IndexReader.MaxDoc();

                Term startTerm = new Term(_TermName.ToString());
                TermEnum te = _IndexReader.Terms(startTerm);
                if (te != null)
                {
                    Term currTerm = te.Term();

                    while ((currTerm != null) && (currTerm.Field() == startTerm.Field())) //term fieldnames are interned
                    {
                        //if (te.DocFreq() > 1)
                        //{
                        TermDocs td = _IndexReader.TermDocs(currTerm);
                        while (td.Next())
                        {
                            dict.Add(td.Doc(), currTerm.Text());
                        }
                        //}
                        if (!te.Next())
                        {
                            break;
                        }
                        currTerm = te.Term();
                    }
                }
            }
            return dict;
        }

        //private static void UpdateTermCache(TermName _TermName, TermCacheName _TermCacheName, IndexReader _IndexReader, ModelFieldCache modelFieldCache)
        //{
        //int oldMaxDoc = CacheDic[_TermCacheName.ToString()].MaxDoc;
        //int newMaxDoc = _IndexReader.MaxDoc();
        //modelFieldCache = CacheDic[_TermCacheName.ToString()];
        //if (oldMaxDoc < newMaxDoc)
        //{
        //    Term startTerm = new Term(_TermName.ToString());
        //    TermEnum te = _IndexReader.Terms(startTerm);
        //    if (te != null)
        //    {
        //        Term currTerm = te.Term();
        //        while ((currTerm != null) && (currTerm.Field() == startTerm.Field())) //term fieldnames are interned
        //        {
        //            //if (te.DocFreq() > 1)
        //            //{
        //            TermDocs td = _IndexReader.TermDocs(currTerm);
        //            if (td.SkipTo(oldMaxDoc))
        //            {
        //                do
        //                {
        //                    modelFieldCache.FieldValueCache.Add(td.Doc(), currTerm.Text());
        //                }
        //                while (td.Next());
        //            }
        //            //}
        //            if (!te.Next())
        //            {
        //                break;
        //            }
        //            currTerm = te.Term();
        //        }
        //    }
        //    modelFieldCache.MaxDoc = newMaxDoc;
        //    CacheDic[_TermCacheName.ToString()] = modelFieldCache;
        //}
        //}
    }

    //public class ModelFieldCache
    //{
    //    private Dictionary<int, string> _FieldValueCache = new Dictionary<int, string>();
    //    private int _MaxDoc = 0;

    //    public Dictionary<int, string> FieldValueCache { get { return _FieldValueCache; } set { _FieldValueCache = value; } }
    //    public int MaxDoc { get { return _MaxDoc; } set { _MaxDoc = value; } }
    //}
}
